package com.datacoper.remotecommands;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.text.MessageFormat;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;

public class RCClient {

  public static void main(String[] args) throws Exception {

    Options options = buildOptions();
        
    try{
      CommandLine commandLine = buildCommandLine(options, args);
      
      int port = getPort(commandLine);
      String host = getHost(commandLine);
      
      String commmands = getCommand(commandLine);
      
      boolean success = connectAndExecute(host, port, commmands); 
          
      if(success){
        System.out.println("Commando executado com Sucesso!");
      }else{
        System.out.println("Commando não executado!");
      }
    
    }catch(ParseException e){
      System.out.println(e.getMessage());
      printHelp(options);
    }
  }
  
  /*
   * ex: asadmin restart-domain domain1
   */
  private static boolean connectAndExecute(String host, int port, String commands) throws Exception{
    
    String[] split = commands.split(" ");
    
    String commandMain = split[0];
    
    String[] args = new String[commands.length() - 1];
    
    for (int i = 1; i < split.length; i++) {
      args[i - 1] = split[i];
    }
        
    ICommandClient command = CommandFactory.createCommand(commandMain);
    
    Socket socket = new Socket(host, port);
    
    return command.execute(socket, args);
  }

  private static int getPort(CommandLine commandLine) {

    int port = RCDefaults.PORT;

    if (commandLine.hasOption('p')) {
      port = Integer.parseInt(commandLine.getOptionValue('p'));
    }

    return port;
  }
  
  private static String getHost(CommandLine commandLine) {

    String host = RCDefaults.HOST;

    if (commandLine.hasOption('h')) {
      host = commandLine.getOptionValue('h');
    }

    return host;
  }
  
  private static String getCommand(CommandLine commandLine) throws ParseException {

    if (commandLine.hasOption('c')) {
      return commandLine.getOptionValue('c');
    }
    
    throw new ParseException("Argumento -c não encontrado");
  }

  private static CommandLine buildCommandLine(Options options, String[] args) throws ParseException {
    CommandLineParser parser = new GnuParser();

    return parser.parse(options, args);
  }

  private static Options buildOptions() {
    Options options = new Options();

    options.addOption("p", "port", true, "Remote Port");
    options.addOption("h", "host", true, "Remote Host");
    options.addOption("c", "command", true, "Remote Command");

    return options;
  }
  
  private static void printHelp(Options options){
    HelpFormatter helpFormatter = new HelpFormatter();
    helpFormatter.printHelp(RCClient.class.getSimpleName(), options);
  }
  
  
  private static void sendFile(Socket socket, String path) throws Exception{
    
    File file = new File(path);
    if(!file.exists()){
      throw new Exception(MessageFormat.format("Arquivo {0} não encontrado.", file.getAbsoluteFile()));
    }
    
    byte[] bytes = new byte[(int)file.length()];
    
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    
    bis.read(bytes, 0, bytes.length);
    
    OutputStream outputStream = socket.getOutputStream();
    
    outputStream.write(bytes, 0, bytes.length);
    outputStream.flush();
    
    bis.close();
  }

}
